package org.datascooter.cglib.proxy.test;

import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap;

import net.sf.cglib.core.ClassGenerator;
import net.sf.cglib.core.DefaultGeneratorStrategy;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import net.sf.cglib.transform.TransformingClassGenerator;
import net.sf.cglib.transform.impl.AddPropertyTransformer;

public class JdkCompatibleProxy implements Serializable {

	private static final Class thisClass = JdkCompatibleProxy.class;
	private static final HandlerAdapter nullInterceptor = new HandlerAdapter(null);
	private static Map generatedClasses = Collections.synchronizedMap(new WeakHashMap());
	private static class HandlerAdapter implements MethodInterceptor {

		private InvocationHandler handler;

		public HandlerAdapter(InvocationHandler handler) {
			this.handler = handler;
		}

		@Override
		public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
			return handler.invoke(obj, method, args);
		}
	}

	protected JdkCompatibleProxy() {
		Enhancer e = new Enhancer();
		// e.setSuperclass(...);
		// etc.
		final Type[] ss = new Type[] {
			Integer.TYPE
		};
		e.setStrategy(new DefaultGeneratorStrategy() {

			protected ClassGenerator transform(ClassGenerator cg) {
				return new TransformingClassGenerator(cg, new AddPropertyTransformer(new String[] {
					"foo"
				}, (net.sf.cglib.asm.Type[]) ss));
			}
		});
		e.setStrategy(new DefaultGeneratorStrategy() {

			protected byte[] transform(byte[] b) {
				return b;
				// do something with bytes here
			}
		});
	}
}
